 /**
 * @author Richie
 * @constructor 
 */
NumberUtils = function () {
	/**
	 * <b>判斷傳入值是否為數值</b>
	 * @param 	checkNum 欲判斷之數值
	 * @return	boolean值
	 */
	this.isNumber = function (checkNum){
		var result = true;
		if((isNaN(checkNum)) || (checkNum == "")){
			result = false;
		}
		return result;
	};

	/**
	 * <b>判斷傳入值是否為整數</b><br/>
	 * @param	checkInt 欲判斷之數值
	 * @return	boolean值
	 */
	this.isInteger = function (checkInt){
		var result = false;
		if((!isNaN(checkInt)) && ((checkInt - parseInt(checkInt, 10)) == 0) && ((checkInt + "").indexOf(".") == -1)){
			result = true;
		}
		return result;
	};

	/**
	 * <b>限制僅限數字輸入</b><br/>
	 * 使用方法：onkeypress="NumberUtil.setNumConstraint(event, this)"
	 * @param	obj 使用物件
	 * @return	字元
	 */
	this.setNumConstraint = function (e, obj){
		var iKeyCode = window.event?e.keyCode:e.which;
		var isIE = false;
		var isFF = false;
		
		/*
		 * ie9: parseInt(navigator.appVersion)=5
		 * ie6: parseInt(navigator.appVersion)=4
		 * ie9的event跟firefox的物件為同一物件型態，故parseInt(navigator.appVersion)限定ie8以下
		 */
//		if ((navigator.userAgent.indexOf("MSIE")>0) && (parseInt(navigator.appVersion) >= 4)){
		if ((navigator.userAgent.indexOf("MSIE")>0) && (parseInt(navigator.appVersion) == 4)){
			isIE = true;
		}
		
		if (navigator.userAgent.indexOf("Firefox")>0){
			isFF = true;
		}
		//if(!(((iKeyCode >= 48) && (iKeyCode <= 57)) || (iKeyCode == 13) || (iKeyCode == 46) || (iKeyCode == 45) || (iKeyCode == 37) || (iKeyCode == 39) || (iKeyCode == 8) || (iKeyCode == 47))){
		
		if(iKeyCode == 45){
			if(obj.value.indexOf("-")>=0){
				if (isIE){
					e.returnValue = false;
				}else{
					e.preventDefault();   //重要 firefox是用prevenDefault()来取消事件的
				}
			}else{
				if (isIE){
					e.returnValue = false;
				}else{
					e.preventDefault();   //重要 firefox是用prevenDefault()来取消事件的
				}
				obj.value = "-" + obj.value;
			}
			return false;
		}
		
		if(iKeyCode == 46 && obj.value.indexOf(".")>=0){
			if (isIE){
				e.returnValue = false;
			}else{
				e.preventDefault();   //重要 firefox是用prevenDefault()来取消事件的
			}
			return false;
		}
		if(!(((iKeyCode >= 48) && (iKeyCode <= 57)) || (iKeyCode == 45 || iKeyCode == 46))){
			if (isIE){
				e.returnValue = false;
			}else{
				e.preventDefault();   //重要 firefox是用prevenDefault()来取消事件的
			}
		}
	};
	
	/**
	 * <b>自動千分位</b><br/>
	 * 使用方法：onblur="NumberUtil.formatNumber(event, this)"
	 * @param	obj 使用物件
	 * @return	字元
	 */
	this.formatNumber = function (e, obj){
		var value = obj.value;
		value = value.replace(/[^0-9.-]/g,'');
		value = value.replace(/\,/g, "");
		
		var temp = "";
		var tempPoint = "";
		value = String(value);
		if(value.indexOf("-")>0){
			temp = "-";
			value = value.substring(1);
		}

		if(value.indexOf(".")>0){
			tempPoint = value.substring(value.indexOf("."));
			value = value.substring(0, value.indexOf("."));
		}
		var re=/(-?\d+)(\d{3})/;
		if(value != ""){
			value = String(Number(value));
			while(re.test(value)){ 
				value = value.replace(re, "$1,$2");
			}
			obj.value =  temp + value + tempPoint;
		}
	};

	/**
	 * <b>數值千位化</b><br/>
	 * 如：1000 - >1,000<br/>
	 * @param	origStr 原本字串
	 * @param	pTypeStr 千位化的分隔字串(ex , ...)
	 * @param	pDSign "" -> 傳回千位化之數值；"$" -> 傳回千位化之數值且加 $
	 * @return	Object，內含 4 項子類別
	 * 			<li>Object.eErr		boolean值，判斷千位化執行情況</li>
	 * 			<li>Object.eNum		正確格式數值(原值)</li>
	 * 			<li>Object.eNum999	正確格式數值</li>
	 * 		 	<li>Object.eErrDesc	執行失敗錯誤訊息</li>
	 */
	this.gfcTrnNumFormat = function (pNum,pTypeStr,pDSign)
	{
		var tNum;
		var tNumStr;
		var tDecStr = "";
		var tPos;
		var ixCount,ixI;
		var tobjResult = new Object();

		//給初值
		tobjResult.eErr = false;
		tobjResult.eNum = pNum;
		tobjResult.eNum999 = "";
		tobjResult.eErrDesc = "";

		//例外處理(傳入空白或 null)
		if (typeof(pDSign) == "undefined") {   pDSign = "";}

		if (pNum == null)
		{
			tobjResult.eNum999 = null;
			return tobjResult;
		}
		if (pNum == "")
		{
			tobjResult.eNum999 = "";
			return tobjResult;
		}

		//例外處理(傳入非數值(字串)或數值位數小於 4)
		if (typeof(pNum) == "string")
		{   
			tNum = parseFloat(pNum,10);
			tNumStr = pNum;

			tPos = tNumStr.indexOf(".");
			if (tPos != -1)
			{
				tDecStr = this.gfcMid(tNumStr,tPos);
				tNumStr = this.gfcMid(tNumStr,0,tPos);
				tNum = parseInt(tNumStr,10);
			}
		}
		else
		{   
			tNum = pNum;
			tNumStr = pNum.toString();

			tPos = tNumStr.indexOf(".");
			if (tPos != -1)
			{
				tDecStr = this.gfcMid(tNumStr,tPos);
				tNumStr = this.gfcMid(tNumStr,0,tPos);
				tNum = parseInt(tNumStr,10);
			}
		}

		if (isNaN(tNum) || tNum != tNumStr)
		{
			tobjResult.eErr = true;
			tobjResult.eNum999 = pNum;
			tobjResult.eErrDesc = "格式錯誤,欲轉換的值不是數值型態 !";
			return tobjResult;
		}
		else
		{
			if (tNumStr.length <= 3)
			{
				if (pDSign.indexOf("$") != -1)
				{   tobjResult.eNum999 = "$ " + pNum;}
				else
				{   tobjResult.eNum999 = pNum;}
				return tobjResult;
			}
		}

		//開始轉換三位一撇
		ixCount = parseInt(tNumStr.length,10) % 3;
		if (ixCount == 0)
		{   ixCount = 3;}

		tNum999 = "";
		tNum999 = tNum999 +  pTypeStr + this.gfcMid(tNumStr,0,ixCount);
		for (ixI=ixCount;ixI<tNumStr.length;ixI=ixI+3)
		{
			tNum999 = tNum999 +  pTypeStr + this.gfcMid(tNumStr,ixI,3);
		}

		if (pDSign.indexOf("$") != -1)
		{   tobjResult.eNum999 = "$ " + tNum999.substring(1) + tDecStr;}
		else
		{   tobjResult.eNum999 = tNum999.substring(1) + tDecStr;}

		return tobjResult;
	};

	/**
	 * <b>將數值 -> 四捨五入, 無條件捨去, 無條件進位</b>
	 * @param	origNum 原本數值
	 * @param	length 小數部分長度, 亦即計算到小數第N位(0,1,2....)
	 * @return	Object，內含 5 項子類別
	 * 			<li>Object.eErr		boolean值，判斷是否為數值型態</li>
	 * 			<li>Object.eRound	四捨五入到小數第length位</li>
	 * 			<li>Object.eFix		無條件捨去到小數第pPoint位</li>
	 * 		 	<li>Object.eAdd		無條件進位到小數第pPoint位</li>
	 * 			<li>Object.ePos		+ / - ，判斷傳入數值為正數 or 負數</li>
	 */
	this.gfcTrnNum = function (pNumStr,pPoint)
	{
		var tobjRtn = new Object();
		var tDecLen = 0;             //-數值的小數部分長度
		var tNumStr;                  //-傳入數值轉成字串
		var tDecPos;                 //-小數點所在位置
		var tPointPow;                //-傳入小數位數的10乘羃
		if (isNaN(pNumStr) == true)  //-判斷傳入值 非數值；傳回錯誤
		{   
			tobjRtn.eErr = true;
			return tobjRtn;
		}
		tobjRtn.eErr = false;
		if (pNumStr == null || pNumStr == "")  //-為 Null / 空白 時; 傳入值=傳回值
		{
			tobjRtn.eRound = pNumStr;
			tobjRtn.eFix   = pNumStr;
			tobjRtn.eAdd   = pNumStr;
			tobjRtn.ePos   = pNumStr;
			return tobjRtn;
		}
		if (isNaN(pPoint) == true || pPoint == null || pPoint == "") //-未傳入小數位數, Default=0
		{   pPoint = 0;  }

		//-取數值的小數位數, 放在變數 tDecLen 中
		tNumStr = pNumStr.toString();
		tDecPos = tNumStr.indexOf(".");  
		if (tDecPos > 0)
		{   tDecLen = tNumStr.substr(tDecPos + 1).length;    }

		//-取數值的正負數
		if (tNumStr >= 0)
		{   tobjRtn.ePos = "+";    }
		else
		{   tobjRtn.ePos = "-";   }
		tNumStr = Math.abs(tNumStr);
		//-若小數位數超過定義則轉換格式
		if (tDecLen > pPoint)
		{
			tPointPow = Math.pow(10,pPoint);  //-要取到小數點n位就有n個0
			tNumStr   = (parseFloat(tNumStr) * tPointPow);
			tobjRtn.eRound = this.gfcAddZero(Math.round(tNumStr) / tPointPow, pPoint);
			tobjRtn.eFix   = this.gfcAddZero(parseInt(tNumStr, 10) / tPointPow, pPoint);
			tobjRtn.eAdd   = this.gfcAddZero((parseInt(tNumStr, 10) + 1) / tPointPow, pPoint);
		}
		else  //若是小數位數不足則傳原數值回去
		{
			tobjRtn.eRound = this.gfcAddZero(tNumStr, pPoint);
			tobjRtn.eFix   = this.gfcAddZero(tNumStr, pPoint);
			tobjRtn.eAdd   = this.gfcAddZero(tNumStr, pPoint);
		}
		if (tobjRtn.ePos == "-")   //-若為負數則補負號
		{
			tobjRtn.eRound = "-" + tobjRtn.eRound;
			tobjRtn.eFix   = "-" + tobjRtn.eFix;
			tobjRtn.eAdd   = "-" + tobjRtn.eAdd;
		}
		return tobjRtn;
	};

	/**
	 * <b>將數值之小數長度右補0至預計之小數長度</b>
	 * 如：12.9 -> 12.9000<br/>
	 * @param	origStr 原本字串
	 * @param	length 預計小數部分長度, 亦即計算到小數第N位(0,1,2....)
	 * @return	字串
	 */
	this.gfcAddZero = function (origStr, length) {
		var result = "";
		var tDecPos;            //小數點所在位置
		var tDecLen = 0;        //數值的小數部分長度
		result = origStr.toString();
		//取得小數點所在位置
		tDecPos = result.indexOf(".");  
		if (tDecPos > 0){   
			tDecLen = result.substr(tDecPos + 1).length;    
		}
		if ((length <= 0) || (tDecLen >= length)){ 
			return origStr;   
		}
		if (tDecLen <= 0 ){   
			result += ".";  
		}
		for (var i=0; i<(length - tDecLen); i++) {
			result += "0";
		}
		return result;
	};

	/**
	 * <b>截取固定長度的字串</b>
	 * @param	origStr 原本字串
	 * @param	startPosition 要截取的起始位置(中文2byte,英文1byte, 以0起算)
	 * @param	length 要截取的真實長度(中文2byte,英文1byte)
	 * @return	字串
	 */
	this.gfcMid = function (origStr, startPosition, length) {
		var result = "";
		var tempStr = "";
		var tempPosition = 0;
		var tempCode;
		
		if (this.gfcLen(origStr) < startPosition ) {
			result = "";
		    return result;
		}
		
		//截掉起始位置前的字串
		for (var i=0; i<origStr.length; i++) {
		    if (startPosition <= 0) {
		    	break;    
		    }
		    tempCode = origStr.charCodeAt(i);
		    if ((tempCode >= 128) || (tempCode < 0)) {
		    	startPosition = startPosition - 2;
		    	tempPosition = tempPosition + 1;
		    } else {
		    	startPosition = startPosition - 1;
		    	tempPosition = tempPosition + 1;
		    }
		}
		origStr = origStr.substring(tempPosition);

		//取得固定長度的字串
		for (var i=0; i<origStr.length; i++) {
		    if( length <= 0 ) { 
		    	break; 
		    }
		    tempStr = origStr.substring(i, (i+1));
		    tempCode = origStr.charCodeAt(i);
		    if ((tempCode >= 128) || (tempCode < 0)) {
		    	length = length - 2;
		    	result = result + tempStr;
		    } else {
				length = length - 1;
				result = result + tempStr;
		    }
		}
		return result;
	};

	/**
	 * <b>以byte為單位計算字串的長度</b>
	 * @param	checkStr 欲計算長度的字串
	 * @return	字串的長度
	 */
	this.gfcLen = function (checkStr) {
		var result = 0;
		var tCode;
		for (var i=0; i<checkStr.length; i++) {
		    tCode = checkStr.charCodeAt(i);
		    if ((tCode >= 128) || (tCode < 0)) {
		    	result = result + 2;
		    } else {   
		    	result = result + 1;
		    }
		}
		return result;
	};
}

var NumberUtils = new NumberUtils();